﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.Resources;
using System.Collections;
using System.Globalization;

namespace blackhouse.Web {
	public class ResourceWebManager {

		#region Fields

		private Dictionary<string, Dictionary<string, object>> resourceData;
		private string resourceFile;
		private HttpContext context = HttpContext.Current;

		#endregion

		public ResourceWebManager(string resourceBaseFile) {
			this.resourceFile = resourceBaseFile;
			this.resourceData = this.GetFromCache();
			if (this.resourceData == null) {
				this.resourceData = this.ReadFromResources();
				this.AddToCache();
			}
		}

		#region Methods

		public string GetString(string key) {
			return this.GetString(key, "");
		}

		public string GetString(string key, string defaultValue) {
			object val = this.Get(key);
			if (val != null)
				return val.ToString();
			else
				return defaultValue;
		}

		public object Get(string key) {
			if (!this.resourceData.ContainsKey(key)) return null;

			string langKey = CultureInfo.CurrentCulture.Name;

			if (this.resourceData[key].ContainsKey(langKey))
				return this.resourceData[key][langKey];

			langKey = langKey.Split('-')[0];
			if (this.resourceData[key].ContainsKey(langKey))
				return this.resourceData[key][langKey];

			return this.resourceData[key]["base"];

		}

		private void AddToCache() {
			this.context.Cache.Add(resourceFile,
					this.resourceData,
					new System.Web.Caching.CacheDependency(this.context.Server.MapPath(this.resourceFile)),
					System.Web.Caching.Cache.NoAbsoluteExpiration,
					TimeSpan.FromMinutes(20),
					System.Web.Caching.CacheItemPriority.Low, null);
		}

		private Dictionary<string, Dictionary<string, object>> GetFromCache() {
			return this.context.Cache[this.resourceFile] as Dictionary<string, Dictionary<string, object>>;
		}

		private Dictionary<string, Dictionary<string, object>> ReadFromResources() {
			Dictionary<string, Dictionary<string, object>> resourceData = new Dictionary<string, Dictionary<string, object>>();
			FileInfo fiBase = new FileInfo(this.context.Server.MapPath(this.resourceFile));

			if (fiBase.Exists) {
				using (FileStream fsBase = fiBase.Open(FileMode.Open, FileAccess.Read, FileShare.Read)) {
					ResXResourceReader rrr = new ResXResourceReader(fsBase);
					IDictionaryEnumerator rren = rrr.GetEnumerator();
					while (rren.MoveNext()) {
						resourceData.Add(rren.Key.ToString(), new Dictionary<string, object>());
						resourceData[rren.Key.ToString()].Add("base", rren.Value);
					}
				}

				FileInfo[] fiLangFiles = fiBase.Directory.GetFiles(fiBase.Name.ReplaceEx("resx", "") + "*" + ".resx");
				foreach (FileInfo fiLang in fiLangFiles) {
					string[] fiLangNameParts = fiLang.Name.Split('.');
					if (fiLangNameParts.Length < 3) continue;
					string langKey = fiLangNameParts[fiLangNameParts.Length - 2];
					using (FileStream fsLang = fiLang.Open(FileMode.Open, FileAccess.Read, FileShare.Read)) {
						ResXResourceReader rrr = new ResXResourceReader(fsLang);
						IDictionaryEnumerator rren = rrr.GetEnumerator();
						while (rren.MoveNext()) {
							string key = rren.Key.ToString();
							if (resourceData.ContainsKey(key)) {
								resourceData[key].Add(langKey, rren.Value);
							}
						}
					}
				}

			}
			return resourceData;
		}

		#endregion

	}
}